﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Synchronization.Files;
using LitS3;
using System.IO;

namespace Natol.MSSyncFxProviders.AmazonS3
{
    /// <summary>
    /// Implements the IFileDataRetreiver properties neccessary to use the microsoft sync framework with a filesyncprovider and the awss3syncprovider
    /// as explained at: http://msdn.microsoft.com/en-us/library/microsoft.synchronization.files.ifiledataretriever%28SQL.105%29.aspx
    /// </summary>
    public class AWSS3FileDataRetriever : IFileDataRetriever
    {
        #region Object Variables
        S3BucketLoginData LoginData { get; set; }
        S3Service Service { get; set; }
        string ObjectKey { get; set; }
        DateTime LastModified { get; set; }
        long ObjectDataSize { get; set; }
        #endregion ObjectVariables

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="loginData"></param>
        /// <param name="objectKey"></param>
        public AWSS3FileDataRetriever(S3BucketLoginData loginData, string objectKey, DateTime lastModified, long objectDataSize)
        {
            //set the object details
            LoginData = loginData;
            ObjectKey = objectKey;
            LastModified = lastModified;
            ObjectDataSize = objectDataSize;

            //initialise
            Service = LoginData.GetService("~");
        }

        #region IFileDataRetriever Members
        

        /// <summary>
        /// Not implemented. Use the FileStream property to gain access to the object's data
        /// </summary>
        public string AbsoluteSourceFilePath
        {
            get 
            {
                //as explained at: http://social.microsoft.com/Forums/en-US/synctechnicaldiscussion/thread/1b37437c-7644-4723-87a6-835f3044b9c2
                //the filesyncprovider will use the filestream (System.IO.Stream) if this throws a NotImplementedException
                throw new NotImplementedException(); 
            }
        }

        /// <summary>
        /// Returns metadata associated with the file as it is represented on Amazon S3
        /// </summary>
        public FileData FileData
        {
            get 
            {
                return new FileData(
                    ObjectKey.Replace('/', '\\'),
                    FileAttributes.Normal,
                    LastModified,
                    LastModified,
                    LastModified,
                    ObjectDataSize
                    );
            }
        }

        /// <summary>
        /// Gets a stream of data from the object on Amazon S3. It is the consumer's responsibility to close the stream.
        /// </summary>
        public System.IO.Stream FileStream
        {
            get 
            {
                try
                {
                    MemoryStream ms = new MemoryStream();
                    using (var str = Service.GetObjectStream(LoginData.BucketName, ObjectKey))
                    {
                        S3Helper.CopyStream(str, ms, this.ObjectDataSize, null);
                    }
                    ms.Position = 0;
                    return ms;
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }
        }

        /// <summary>
        /// Gets the relative directory path of the object, without the filename
        /// </summary>
        public string RelativeDirectoryPath
        {
            get 
            {
                return Path.GetDirectoryName(ObjectKey.Replace('/','\\'));
            }
        }

        #endregion
    }
}
